package vip.xiaonuo.common.mvc.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.common.mapper.BaseMapperPlus;
import vip.xiaonuo.common.mvc.service.BaseService;
import vip.xiaonuo.common.page.PageQuery;
import vip.xiaonuo.common.pojo.CommonEntity;
import vip.xiaonuo.common.util.MapstructUtils;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * @author zjt
 * @description
 * @date 2025/4/1 16:41
 */
@RequiredArgsConstructor
public abstract class BaseServiceImpl<Bo, Vo, Q extends PageQuery, Mapper extends BaseMapperPlus<Entity, Vo>, Entity extends CommonEntity>
        implements BaseService<Bo, Vo, Q> {

    protected final Mapper baseMapper;

    @Override
    public Page<Vo> pageList(Q queryBo) {
        return baseMapper.selectVoPage(new Page<>(queryBo.getCurrent(), queryBo.getSize()), buildQueryWrapper(queryBo));
    }

    /**
     * 查询详情
     *
     * @param id
     * @return
     */
    @Override
    public Vo selectVoById(Long id) {
        return baseMapper.selectVoById(id);
    }

    /**
     * 插入一个新的业务对象。
     *
     * @param bo 业务对象
     */
    @Override
    public void insert(Bo bo) {
        insertBefore(bo);
        baseMapper.insert(MapstructUtils.convert(bo, getEntityClass()));
        insertAfter(bo);
    }

    /**
     * 更新一个已存在的业务对象。
     *
     * @param bo 业务对象
     */
    @Override
    public void update(Bo bo) {
        updateBefore(bo);
        baseMapper.updateById(MapstructUtils.convert(bo, getEntityClass()));
        updateAfter(bo);
    }

    /**
     * 根据主键 ID 删除一个业务对象。
     *
     * @param id 主键 ID
     */
    @Override
    public void delete(Long id) {
        baseMapper.deleteById(id);
    }

    protected abstract LambdaQueryWrapper<Entity> buildQueryWrapper(Q queryBo);

    protected Class<Entity> getEntityClass() {
        // 获取当前类的泛型参数列表（对应父类 BaseServiceImpl 的泛型声明顺序）
        Type genericSuperclass = this.getClass().getGenericSuperclass();
        if (genericSuperclass instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
            // 根据泛型参数顺序获取 Entity 类型（第5个泛型参数，索引4）
            Type entityType = actualTypeArguments[4];
            if (entityType instanceof Class<?>) {
                return (Class<Entity>) entityType;
            }
        }
        throw new CommonException("无法获取 Entity 类型");
    }

    /**
     * 新增的前置校验
     *
     * @param bo
     */
    protected void insertBefore(Bo bo) {

    }

    /**
     * 新增的后置校验
     *
     * @param bo
     */
    protected void insertAfter(Bo bo) {

    }

    /**
     * 修改的前置校验
     *
     * @param bo
     */
    protected void updateBefore(Bo bo) {

    }

    /**
     * 修改的后置校验
     *
     * @param bo
     */
    protected void updateAfter(Bo bo) {

    }
}
